<template>
    <div id="map" ref="mapRef">

    </div>
</template>

<script>
    import {Map, View} from 'ol'
    import OSM from 'ol/source/OSM'
    import TileLayer from 'ol/layer/Tile'
    import {XYZ} from 'ol/source';
    import {defaults as defaultControls} from 'ol/control.js';
    import {defaults as defaultInteractions} from 'ol/interaction.js';
    import {Zoom} from 'ol/control';
    import {DragPan} from 'ol/interaction';
    export default {
        name: "MapDesc",
        data() {
            return {
                map: null
            }
        },
        mounted(){
            this.map = new Map({
                target:"map",//用id标识挂载的dom对象
                // target:this.$refs.mapRef,//挂载的dom对象
                layers:[
                    new TileLayer({ //图层按提供的顺序呈现
                        title: "OpenStreetMap",
                        source: new OSM()
                    }),
                    new TileLayer({
                        title: "天地图路网",
                        source: new XYZ({url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=5ceba6b01e36e130d9506f00dac50595"}),
                        name: "tdtLayer",
                        data: "aaa"
                    })
                ],
                controls: defaultControls({
                    attribution: true,//禁用右下角的地图属性组件
                    rotate: false,//禁用旋转组件 alt+shift true旋转交互时会有一个旋转控件显示出来
                    zoom: false//禁用右上角缩放组件
                }),//地图控件
                pixelRatio: window.devicePixelRatio,//物理像素与css像素分辨率的比值
                interactions: defaultInteractions({
                    altShiftDragRotate: true,//禁用按住alt+shift拖拽旋转
                    doubleClickZoom: true,//禁用双击缩放
                    dragPan: true//禁用平面拖拽
                }),//默认交互
                maxTilesLoading: 16,//同时加载的最大的瓦片数量，默认是16
                moveTolerance: 5,//光标必须移动的最小距离（以像素为单位）才能被检测为地图移动事件而不是单击
                //overlays:"",//叠加层,例如地图标注，气泡窗等
                //配置视图
                view: new View({
                    center: [113.24981689453125, 23.126468438108688], //视图中心位置
                    projection: "EPSG:4326", //指定投影
                    zoom: 12   //缩放级别
                })
            });

            //change事件
            //this.changeEventHandler();
            //点击事件
            //this.clickEventHandler();
            //发生错误时触发
            //this.errorEventHandler();
            //地图移动事件
            //this.moveEventHandler()
            //触摸设备事件
            //this.pointerEventHandler()
            //图层事件
            //this.postEventHandler()
            //渲染完成时触发，即当前视口的所有源和图块都已完成加载，并且所有图块都淡入
            //this.renderEventHandler();
            //当Map对象属性改变时触发
            // this.propertyEventHandler()
            // setTimeout(()=>{
            //     //this.map.setSize(1000)
            //     this.map.setProperties('aa','aa')
            //     // this.map.setProperties('aa','bb')
            // },1000)


            /*####################################Map方法处理#####################################*/


            //add开头方法
            //this.addMethodHnadler();
            //get开头方法
            //this.getMethodHnadler();
            //on开头方法
            //this.onMethodHandler()
            //remove开头方法
            //this.removeMethodHandler();
            //set开头方法
            this.setMethodHandler()
        },
        methods:{
            /*####################################Map事件处理#####################################*/
            changeEventHandler() {
                //通用更改事件。当修订计数器增加时触发。
                this.map.on("changed", (event) => {
                    console.log(event)
                    //map对象的属性只要有改变，就会修改此对象的版本号，版本号变化了，此事件就会触发
                })
                // change:size事件
                this.map.on('change:size', (event) => {
                    console.log('size改变');
                    //屏幕尺寸变化的回调
                });

                // change:view事件
                this.map.on('change:view', (event) => {
                    console.log('view改变');
                });
                // change:target事件
                this.map.on('change:target', (event) => {
                    console.log('target改变');
                });
                // change:layerGroup事件
                this.map.on('change:layerGroup', (event) => {
                    console.log('target改变');
                    //图层动态变化，图例动态变化
                });
            },
            clickEventHandler() {
                // click事件,双击触发两次,点多少次都会触发
                this.map.on('click', (event) => {
                    console.log('click');
                });
                //双击事件，没有拖动
                this.map.on('dblclick', (event) => {
                    console.log('dblclick');
                });
                //真正的单击，没有拖动和双击。请注意，此事件会延迟 250 毫秒，以确保它不是双击。
                this.map.on('singleclick', (event) => {
                    console.log('singleclick ');
                });
            },
            errorEventHandler() {
                // 地图发生错误触发
                this.map.on('error', (event) => {
                    console.log('error');
                });
            },
            moveEventHandler() {
                //地图开始移动事件
                this.map.on('movestart', (event) => {
                    console.log('movestart ',event);
                });
                //地图移动结束事件
                this.map.on('moveend', (event) => {
                    console.log('moveend',event);
                });
            },
            pointerEventHandler() {
                //地图触摸拖拽事件
                this.map.on('pointerdrag', (event) => {
                    console.log('pointerdrag');
                });
                //地图触摸移动事件
                this.map.on('pointermove', (event) => {
                    console.log('pointermove');
                });
            },
            postEventHandler() {
                //在渲染图层之前触发，没有设置上下文context
                this.map.on('precompose', (event) => {
                    console.log('precompose');
                });
                //所有图层渲染完后触发，没有设置上下文context
                this.map.on('postcompose', (event) => {
                    console.log('postcompose');
                });
                //地图渲染完成触发
                this.map.on('postrender', (event) => {
                    console.log('postrender');
                });
            },
            renderEventHandler(i) {
                //渲染完成时触发，即当前视口的所有源和图块都已完成加载，并且所有图块都淡入。事件对象将没有上下文设置。
                //监听的是渲染的上下文对象context
                this.map.on('rendercomplete', (event) => {
                    console.log('rendercomplete',1);
                });
            },
            propertyEventHandler() {
                //当属性改变时触发
                this.map.on('propertychange', (event) => {
                    console.log('propertychange');
                });
            },
            /*####################################Map方法处理#####################################*/
            //add开头的方法
            addMethodHnadler() {
                //添加空间
                this.map.addControl(new Zoom())
                //添加交互
                this.map.addInteraction(new DragPan())
                //添加图层瓦片
                this.map.addLayer(new TileLayer({ //图层按提供的顺序呈现
                    title: "OpenStreetMap",
                    source: new OSM(),//加载OpenStreetMap
                    name: "OpenStreetMap"
                }))
                console.log(this.map.getLayers())
                //this.map.addOverlay(overlay) 添加叠加层

                //调度事件并调用所有侦听此类型事件的侦听器
                this.map.on('click', (event) => {
                    console.log('调度事件并调用所有侦听此类型事件的侦听器');
                    this.map.dispatchEvent("dblclick");
                });

                this.map.on('singleclick', event => {
                    let layers = []
                    //检测与视口上的像素相交的layer
                    this.map.forEachLayerAtPixel(event.pixel,
                        (layer) => {
                            console.log(event, layer)
                            layers.push(layer)
                        },
                        {
                            layerFilter: function (layer) {
                                //图层过滤
                                //图层加载了三层所以会有三个layer打印出来
                                console.log(layer, layer.get('name'))
                                return layer.get('name') === 'OpenStreetMap';
                            },
                            hitTolerance: 0,//以 css 像素为单位的命中检测容差。将检查给定位置周围半径内的像素的featrue。
                            checkWrapped: true//将检查 +/- 1 世界宽度范围内的包裹几何图形
                        }
                    );
                    console.log(layers)
                    //检测与视口上的像素相交的featrue
                    let features = []
                    this.map.forEachFeatureAtPixel(event.pixel,
                        (feature) => {
                            console.log(event, feature)
                            features.push(feature)
                        },
                        {
                            layerFilter: function (layer) {
                                //图层过滤
                                return layer.get('name') === 'gz';
                            },
                            hitTolerance: 10,
                            checkWrapped: true
                        }
                    );
                });
            },
            //get开头的方法
            getMethodHnadler() {
                this.map.on('singleclick', event => {
                    //获取到所有的控件
                    let controls = this.map.getControls();
                    console.log(controls)
                    //获取给定像素的投影坐标
                    let coordinateFromPixel = this.map.getCoordinateFromPixel(event.pixel);
                    console.log(coordinateFromPixel)
                    let eventCoordinate = this.map.getEventCoordinate(event.originalEvent);
                    console.log(eventCoordinate)
                    //获取到当前视口的像素
                    let eventPixel = this.map.getEventPixel(event.originalEvent);
                    console.log(eventPixel)
                    let keys = this.map.getKeys();
                    console.log(keys)
                    //获取到map的图层组
                    let layerGroup = this.map.getLayerGroup();
                    console.log(layerGroup)
                    //获取坐标的像素。这需要用户投影中的坐标并返回相应的像素
                    let pixelFromCoordinate = this.map.getPixelFromCoordinate([113.35275651421398, 23.12185264976067]);
                    console.log(pixelFromCoordinate)
                    let properties = this.map.getProperties();
                    console.log(properties)
                    //获取此对象的版本号。每次修改对象时，其版本号都会增加。
                    let revision = this.map.getRevision();
                    console.log(revision)
                    this.map.changed()
                    console.log(this.map.getRevision())
                    //获取到map容器
                    let target = this.map.getTarget();
                    console.log(target)
                    //获取到map容器元素id
                    let targetElement = this.map.getTargetElement();
                    console.log(targetElement)
                    //获取到map的视口
                    let viewport = this.map.getViewport();
                    console.log(viewport)

                    //检测要素是否与视口上的像素相交。可以通过 配置检测中包含的层opt_layerFilter
                    //this.map.hasFeatureAtPixel()
                    this.map.on('click',(e)=>{
                        debugger
                        //屏幕坐标
                        let pixel = this.map.getEventPixel(e.originalEvent);
                        //检测与视口上的像素相交的要素
                        this.map.forEachFeatureAtPixel(pixel,function(feature,layers){
                            //feature,返回的要素
                            console.log(feature)
                            //layers，返回的图层
                            console.log(layers)
                        })
                    })

                })

            },
            //on开头的方法
            onMethodHandler() {
                //事件只绑定一次
                this.map.once("singleclick", event => {
                    console.log("once")
                })
            },
            //remove开头的方法
            removeMethodHandler() {
                let zoom = new Zoom();
                this.map.addControl(zoom)
                let controls = this.map.getControls();
                let len=controls.getArray().length;
                let array = controls.getArray();
                for (let i = 0; i < len; i++) {
                    const control = array[i];
                    this.map.removeControl(control)
                }
                //从地图中删除给定的交互。
                //this.map.removeInteraction(interaction)

                // 从地图中删除给定的图层。
                let layers = this.map.getLayers();
                this.map.removeLayer(layers.getArray()[1])

                // 从地图中删除给定的叠加层。
                // this.map.removeOverlay(overlay)

            },
            //set开头的方法
            setMethodHandler() {
                this.map.setProperties("a","aa")
                let htmlDivElement = document.createElement("div");
                htmlDivElement.id="newMap"
                document.body.appendChild(htmlDivElement);
                this.map.setTarget(htmlDivElement)
                this.map.render();
            },

            unMethodHandler() {
                //不监听某种类型的事件。on对应
                //un(type, listener)

                // 取消设置属性 set对应
                //unset(key, opt_silent)


            },

            updateSize() {
                //强制重新计算地图视口大小
                //updateSize()
            },

            renderMethodHandler() {
                //在下一个动画帧请求地图渲染
                //render()
                //以同步方式请求立即渲染
                //renderSync()

            }
        }
    }
</script>

<style scoped>
    #map {
        width: 100%;
        height: 100%
    }
</style>